package cn.xlbweb.cli.service.impl;

import cn.xlbweb.cli.common.CommonConstant;
import cn.xlbweb.cli.common.CommonEnum;
import cn.xlbweb.cli.repository.UserRepository;
import cn.xlbweb.cli.pojo.dto.UserInsertDTO;
import cn.xlbweb.cli.pojo.dto.UserListDTO;
import cn.xlbweb.cli.pojo.dto.UserUpdateDTO;
import cn.xlbweb.cli.pojo.jdo.RoleDO;
import cn.xlbweb.cli.pojo.jdo.UserDO;
import cn.xlbweb.cli.service.UserService;
import cn.xlbweb.ji.JwtUtils;
import cn.xlbweb.util.ConvertUtils;
import cn.xlbweb.util.response.ServerResponse;
import cn.xlbweb.util.response.TableResponse;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import java.util.*;

/**
 * @author: bobi
 * @date: 2019-02-11 16:02
 * @description:
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public ServerResponse getCurrentUser() {
        String username = JwtUtils.getUsername();
        UserDO userDO = userRepository.findByUsername(username);
        userDO.setPassword(StringUtils.EMPTY);
        return ServerResponse.success("查询用户成功", userDO);
    }

    @Override
    public ServerResponse getUser(Integer id) {
        UserDO userDO = userRepository.getOne(id);
        userDO.setPassword(StringUtils.EMPTY);
        return ServerResponse.success("查询用户成功", userDO);
    }

    @Override
    public TableResponse listUser(UserListDTO dto) {
        Specification<UserDO> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (StringUtils.isNotBlank(dto.getUsername())) {
                predicates.add(criteriaBuilder.like(root.get("username"), "%" + dto.getUsername() + "%"));
            }
            if (StringUtils.isNotBlank(dto.getMail())) {
                predicates.add(criteriaBuilder.like(root.get("mail"), "%" + dto.getMail() + "%"));
            }
            if (StringUtils.isNotBlank(dto.getRoleName())) {
                Join<UserDO, RoleDO> join = root.join("role", JoinType.LEFT);
                predicates.add(criteriaBuilder.like(join.get("roleName"), "%" + dto.getRoleName() + "%"));
            }
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        PageRequest pageRequest = PageRequest.of(dto.getPage() - 1, dto.getSize(), Sort.Direction.DESC, CommonConstant.DEFAULT_ORDER_COLUMN);
        Page<UserDO> page = userRepository.findAll(specification, pageRequest);
        List<UserDO> userDOs = page.getContent();
        userDOs.forEach(userDO -> userDO.setPassword(StringUtils.EMPTY));
        return TableResponse.success("查询用户成功", page.getTotalElements(), page.getContent());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServerResponse insertUser(UserInsertDTO dto) {
        UserDO checkUser = userRepository.findByUsername(dto.getUsername());
        if (Objects.nonNull(checkUser)) {
            return ServerResponse.error("账号已存在");
        }
        UserDO userDO = new UserDO();
        ConvertUtils.copyProperties(dto, userDO);
        // 默认未激活
        userDO.setStatus(CommonEnum.UserStatus.NOT_ACTIVE.getCode());
        userRepository.save(userDO);
        return ServerResponse.success("用户添加成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServerResponse updateUser(UserUpdateDTO dto) {
        UserDO userDO = userRepository.getOne(dto.getId());
        ConvertUtils.copyProperties(dto, userDO);
        userRepository.save(userDO);
        return ServerResponse.success("用户更新成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServerResponse deleteUser(String ids) {
        List<UserDO> userDOs = ConvertUtils.strToIntegerList(ids, UserDO::new);
        userRepository.deleteInBatch(userDOs);
        return ServerResponse.success("用户删除成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServerResponse resetPwd(String ids) {
        List<Integer> idList = ConvertUtils.strToIntegerList(ids);
        for (Integer id : idList) {
            // 生成随机密码
            String newPwd = RandomStringUtils.randomAlphanumeric(10);
            // 更新数据库
            UserDO dbUser = userRepository.getOne(id);
            dbUser.setPassword(DigestUtils.md5DigestAsHex(newPwd.getBytes()));
            userRepository.save(dbUser);
            // 发送邮件
        }
        return ServerResponse.success("用户密码重置成功");
    }
}
